﻿using System;
using System.Net;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.Xml;

namespace NetstsadmService
{
    internal class Host
    {
        const string SERVICE_URL = "http://{0}/NetStsAdmService";

        UriBuilder uriBuilder;
        ServiceHost service;

        internal string ListeningURL
        {
            get { return uriBuilder.ToString(); }
        }

        internal Host(int Port, bool AllowAnonymous)
        {
            uriBuilder = new UriBuilder(string.Format(SERVICE_URL, Environment.MachineName));
            uriBuilder.Port = Port;

            BasicHttpBinding binding = new BasicHttpBinding();

            binding.MaxReceivedMessageSize = 50000000;
            // Redefine the limitation so that large files can be sent over
            XmlDictionaryReaderQuotas xmlDictionaryReaderQuotas = new XmlDictionaryReaderQuotas();
            xmlDictionaryReaderQuotas.MaxArrayLength = 50000000;
            binding.ReaderQuotas = xmlDictionaryReaderQuotas;

            service = new ServiceHost(typeof(Services), uriBuilder.Uri);

            ServiceMetadataBehavior smb = service.Description.Behaviors.Find<ServiceMetadataBehavior>();
            
            // If not, add one
            if (smb == null)
                smb = new ServiceMetadataBehavior();

            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            service.Description.Behaviors.Add(smb);

            service.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, 
                    MetadataExchangeBindings.CreateMexHttpBinding(),
                    "mex");

            binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            if (AllowAnonymous)
            {
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
            }
            else
            {
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
                service.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Windows;
            }

            service.AddServiceEndpoint(typeof(ICommandExecuter), binding, "");
        }

        internal void Start()
        {
            service.Open();                
        }

        internal void Close()
        {
            service.Close();
        }
    }
}
